package com.ruijie.acl.web.config;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.faces.model.ListDataModel;

import junit.framework.Assert;

import org.apache.commons.collections.CollectionUtils;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;

import com.ruijie.acl.task.model.AclInterfaceInfo;
import com.ruijie.acl.utils.AclConfigUtil;
import com.ruijie.acl.utils.AclUtil;
import com.ruijie.batch.execution.PlanExecutionLog;
import com.ruijie.batch.execution.PlanExecutionQuery;
import com.ruijie.batch.execution.PlanStepExecutionLog;
import com.ruijie.batch.execution.StepProcessLog;
import com.ruijie.emp.system.role.service.DeviceSecurityRoleService;
import com.ruijie.foundation.adapter.utils.StringUtils;
import com.ruijie.foundation.web.action.BasePagedSupportAction;

/**
 * <p>
 * Title: ACL部署下发处理日志Action
 * </p>
 * <p>
 * Description: Function Description
 * </p>
 * <p>
 * Copyright: Copyright (c) 2009
 * </p>
 * <p>
 * Company: Ruijie Co., Ltd.
 * </p>
 * <p>
 * Create Time: 2009-10-13
 * </p>
 * <p>
 * Update Time:
 * </p>
 * <p>
 * Updater:
 * </p>
 * <p>
 * Update Comments:
 * </p>
 * 
 * @author ASAI
 */
@Name("aclDeployItemProcessLogAction")
@Scope(ScopeType.CONVERSATION)
public class AclDeployItemProcessLogAction extends BasePagedSupportAction {

	@In("#{planExecutionQuery}")
	private PlanExecutionQuery planExecutionQuery;

	private PlanExecutionLog planExecutionLog;

	private List<StepProcessLog> stepProcessLogs;

	private Long[] stepProcessedCount = new Long[] { 0L, 0L, 0L };

	private String returnUrl;

	public String toDetailPage(PlanExecutionLog planExecutionLog,
			String returnUrl) {
		this.planExecutionLog = planExecutionLog;
		this.returnUrl = returnUrl;
		refresh();
		return "/acl/plan/planExecutionLogDetail.seam";
	}

	public String getTimeRangeNames(StepProcessLog stepProcessLog) {
		if (stepProcessLog != null
				&& stepProcessLog.getItemParameters().containsKey(
						Constants.ACL_DEPLOY_PLAN_ITEM_PARAM_NAME_TIMENAMES)) {
			String timerangeName = stepProcessLog.getItemParameters().get(
					Constants.ACL_DEPLOY_PLAN_ITEM_PARAM_NAME_TIMENAMES);
			if (timerangeName != null){
				timerangeName = timerangeName.replaceAll(",", ", ");
			}
			return timerangeName;
		}
		return "";
	}

	public String getAccessGroupNames(StepProcessLog stepProcessLog) {
		if (stepProcessLog != null
				&& stepProcessLog.getItemParameters().containsKey(
						Constants.ACL_DEPLOY_PLAN_ITEM_PARAM_NAME_GROUPNAMES)) {
			String accessGroupName = stepProcessLog.getItemParameters().get(
					Constants.ACL_DEPLOY_PLAN_ITEM_PARAM_NAME_GROUPNAMES);
			if (accessGroupName != null){
				accessGroupName = accessGroupName.replaceAll(",", ", ");
			}
			return accessGroupName;
		}
		return "";
	}

	public List<AclInterfaceInfo> getInterfaces(StepProcessLog stepProcessLog) {
		if (stepProcessLog != null
				&& stepProcessLog.getItemParameters().containsKey(
						Constants.ACL_DEPLOY_PLAN_ITEM_PARAM_NAME_INTERFACES)) {
			return AclConfigUtil.convertInterfaces(stepProcessLog
					.getItemParameters()
					.get(Constants.ACL_DEPLOY_PLAN_ITEM_PARAM_NAME_INTERFACES));
		}
		return new ArrayList<AclInterfaceInfo>();
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void updateModel() {
		currentPage = planExecutionQuery.pagedQueryStepProcessLog(
				planExecutionLog.getId(), page, pageSize);
		stepProcessLogs = (List<StepProcessLog>) currentPage.getResult();
	}

	public PlanExecutionLog getPlanExecutionLog() {
		return planExecutionLog;
	}

	public void setPlanExecutionLog(PlanExecutionLog planExecutionLog) {
		this.planExecutionLog = planExecutionLog;
	}

	public ListDataModel getStepProcessLogs() {
		if (stepProcessLogs == null) {
			refresh();
		}
		return new ListDataModel(stepProcessLogs);
	}

	public void setStepProcessLogs(List<StepProcessLog> itemProcessLogs) {
		this.stepProcessLogs = itemProcessLogs;
	}

	/**
	 * <p>
	 * Description: 已经处理数
	 * </p>
	 * <p>
	 * Create Time: 2009-1-7
	 * </p>
	 * 
	 * @author ASAI
	 * @param step
	 *            从0开始
	 * @return
	 */
	public Long getProcessedCount(int step) {
		Assert.assertTrue(step >= 0 && step < 3);
		refreshLogData();

		Collection<PlanStepExecutionLog> stepLogs = getPlanExecutionLog()
				.getStepLogs();

		if (step >= stepLogs.size())
			return 0L;

		PlanStepExecutionLog stepLog = (PlanStepExecutionLog) CollectionUtils
				.get(stepLogs, step);

		return stepLog.getProcessCount();
	}

	public void refreshLogData() {
		Collection<PlanStepExecutionLog> stepLogs = null;
		if (getPlanExecutionLog() != null) {
			stepLogs = getPlanExecutionLog().getStepLogs();
			if (stepLogs != null) {
				for (int i = 0; i < stepLogs.size(); i++) {
					PlanStepExecutionLog stepLog = (PlanStepExecutionLog) CollectionUtils
							.get(stepLogs, i);
					stepProcessedCount[i] = stepLog.getProcessCount();
				}
				planExecutionQuery.refresh(getPlanExecutionLog());

				if (needRfreshItemProcessLogs(stepProcessedCount,
						getPlanExecutionLog().getStepLogs()))
					updateModel();
			}
		}
	}

	/**
	 * <p>
	 * Description: 第step步是否结束了
	 * </p>
	 * <p>
	 * Create Time: 2009-1-8
	 * </p>
	 * 
	 * @author ASAI
	 * @param step
	 * @return
	 */
	public boolean isFinish(int step) {
		Assert.assertTrue(step >= 0 && step < 3);
		refreshLogData();
		Collection<PlanStepExecutionLog> stepLogs = null;

		if (getPlanExecutionLog() != null) {
			stepLogs = getPlanExecutionLog().getStepLogs();
			if (stepLogs != null) {
				// Collection<PlanStepExecutionLog> stepLogs =
				// getPlanExecutionLog().getStepLogs();

				if (step >= stepLogs.size())
					return false;

				PlanStepExecutionLog stepLog = (PlanStepExecutionLog) CollectionUtils
						.get(stepLogs, step);
				return stepLog.isFinish();
			}
		}
		return false;
	}

	public boolean isProcessing(int step) {
		Assert.assertTrue(step >= 0 && step < 3);

		Collection<PlanStepExecutionLog> stepLogs = getPlanExecutionLog()
				.getStepLogs();

		if (step >= stepLogs.size())
			return false;

		PlanStepExecutionLog stepLog = (PlanStepExecutionLog) CollectionUtils
				.get(stepLogs, step);
		return stepLog.isProcessing();
	}

	/**
	 * <p>
	 * Description: 第step步骤是否已经开始
	 * </p>
	 * <p>
	 * Create Time: 2009-1-9
	 * </p>
	 * 
	 * @author ASAI
	 * @param step
	 * @return
	 */
	public boolean isStarted(int step) {
		Assert.assertTrue(step >= 0 && step < 3);

		Collection<PlanStepExecutionLog> stepLogs = getPlanExecutionLog()
				.getStepLogs();

		return stepLogs.size() > step;
	}

	/**
	 * <p>
	 * Description: 是否有必要刷新ItemProcessLogs
	 * </p>
	 * <p>
	 * Create Time: 2009-1-7
	 * </p>
	 * 
	 * @author ASAI
	 * @param oldCount
	 * @param stepLogs
	 * @return
	 */
	private boolean needRfreshItemProcessLogs(Long[] oldCount,
			Collection<PlanStepExecutionLog> stepLogs) {
		Long[] newCount = new Long[] { 0L, 0L, 0L };

		for (int i = 0; i < stepLogs.size(); i++) {
			PlanStepExecutionLog stepLog = (PlanStepExecutionLog) CollectionUtils
					.get(stepLogs, i);
			newCount[i] = stepLog.getProcessCount();
		}

		return (oldCount[0] != newCount[0]) || (oldCount[1] != newCount[1])
				|| (oldCount[2] != newCount[2]);
	}

	/**
	 * <p>
	 * Description: 总数
	 * </p>
	 * <p>
	 * Create Time: 2009-1-7
	 * </p>
	 * 
	 * @author ASAI
	 * @param step
	 *            从0开始
	 * @return
	 */
	public Long getTotalItemCount(int step) {
		Assert.assertTrue(step >= 0 && step < 3);

		final Collection<PlanStepExecutionLog> stepLogs = getPlanExecutionLog()
				.getStepLogs();

		if (step >= stepLogs.size())
			return 0L;

		PlanStepExecutionLog stepLog = (PlanStepExecutionLog) CollectionUtils
				.get(stepLogs, step);
		return stepLog.getTotal();
	}

	public boolean enablePull() {
		return !isFinish(2);
	}

	public String getReturnUrl() {
		if (StringUtils.isNullOrEmpty(returnUrl)) {
			return "/acl/plan/planDetail.seam";
		}
		return returnUrl;
	}

	public String getTaskCodeSuffix(String taskCode) {
		String taskCodeSuffix = "";
		if (!AclUtil.empty(taskCode)) {
			taskCodeSuffix = taskCode
					.substring(Constants.ACL_DEPLOY_ACTION_TASK_CODE_PREX
							.length() + 1);
		}
		return taskCodeSuffix;
	}

	@In("#{deviceSecurityRoleService}")
    private DeviceSecurityRoleService deviceSecurityRoleService;
	
	/**
	 * 重写计划执行日志的方法，以便对其涉及到的设备进行过滤
	 * @param planExecutionLog
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public ListDataModel getPlanStepProcessLogs4Acl(PlanExecutionLog planExecutionLog){

		currentPage = deviceSecurityRoleService.pagedQueryStepProcessLog(planExecutionLog.getId(), page, pageSize);
		
		this.setCurrentPage(currentPage);
		
		return new ListDataModel((List<StepProcessLog>)currentPage.getResult());
	}
}
